<?php defined('IN_LK') or die('Access Denied');
/**
 * 公共函数库
 * @author yangzhiguo 2011-04-04
 * @access public 
 */

/**
 * 将文本格式成适合js输出的字符串
 * @param string $string 需要处理的字符串
 * @param intval $isjs 是否执行字符串格式化，默认为执行
 * @return string 处理后的字符串
 */
function format_js($string, $isjs = 1)
{
	$string = addslashes(str_replace(array("\r", "\n"), array('', ''), $string));
	return $isjs ? 'document.write("' . $string . '");' : $string;
}

/**
 * 加密解密(内容，加密OR解密， 密钥)
 */
function lk_auth($str, $type = 'ENCODE', $key = '')
{
	$code = '';
	$str  = $type == 'ENCODE' ? $str : base64_decode($str);
	$slen = strlen($str);
	$klen = strlen($key);
	for($i = 0; $i <$slen; $i++)
	{
		$k = $i / $klen;
		$code .= $str[$i] ^ $key[$k];
	}
	$code = $type == 'DECODE' ? $code : base64_encode($code);
	return $code;
}

/**
 * 数组字段安全性检查
 * @param array  $data 要检查的数组
 * @param array  $fields 安全字段
 * @return array 数组$data中在安全字段$fields中的数组
 */
function in_fields($data, $fields)
{
	if(!is_array($data) || !is_array($fields))
	{
		return false;
	}
	foreach($data as $key => $value)
	{
		if(!in_array($key, $fields))
		{
			unset($data[$key]);
		}
	}
	return $data;
}

/**
 * 检查日期时间格式是否正确
 * @param string $data   内容
 * @param string $format 格式 date=>'0000-00-00', 'time'=>'0000-00-00 00:00:00';
 * @return boolean 正确返回true
 */
function is_datetime($data, $format = 'date')
{
	$d = '-';
	$t = ':';
	$patt = $format == 'date' ? "{^\d{4}($d)\d{2}\\1\d{2}$}" : "{^\d{4}($d)\d{2}\\1\d{2}\s\d{2}($t)\d{2}\\2\d{2}$}";
	return strlen($data)> 8 && preg_match($patt, $data);
}

/**
 * 密码加密
 */
function password($pwd)
{
	$pwd = md5(md5(trim($pwd) . PWD_AUTH));
	return $pwd;
}

/**
 * 检查Email是否合法
 * @return boolean 合法返回true
 */
function is_email($email)
{
	return strlen($email)> 6 && preg_match("/^[\w\-\.]+@[\w\-\.]+(\.\w+)+$/", $email);
}

/**
 * 检查密码是否合法
 * @param string $password
 * @return boolean 合法返回true
 */
function is_password($password)
{
	$len = strlen($password);
	return $len>= PASSWORD_MIN_LENGTH && $len <=PASSWORD_MAX_LENGTH ? true : false;
}

/**
 * 检查用户名受否合法
 * @param string $username
 * @return boolean 合法返回true
 */
function is_username($username)
{
	$len = strlen($username);
	if(is_badstring($username) || !preg_match('/^[a-zA-Z0-9_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]+$/', $username))
	{
		return false;
	}
	if($len> USERNAME_MAX_LENGTH || $len <USERNAME_MIN_LENGTH)
	{
		return false;
	}
	return true;
}

/**
 * 检查非法字符
 * @param string $string
 * @return boolean 含有非法字符返回true
 */
function is_badstring($string)
{
	$words = array("\\",'&',' ',"'",'"','/','*',',','<','>',"\r","\t","\n","#");
	foreach($words as $word)
	{
		if(false !== strpos($string, $word))
		{
			return true;
		}
	}
	return false;
}

/**
 * 字节转换为人读格式
 * @param  int $bytes
 * @return string
 */
function bytes2human($bytes, $units = array())
{
	$units = is_array($units) && $units ? $units : array('B', 'KB', 'MB', 'GB', 'TB');
	foreach($units as $unit)
	{
		if($bytes <1024)
		{
			break;
		}
		$bytes = $bytes / 1024;
	}
	$size = number_format($bytes, 2) . $unit;
	return $size;
}

/**
 * 读取缓存
 * @param string $name 缓存标志
 * @return mixed {成功:array,失败:false}
 */
function get_cache($name)
{
	lk::lo('cache_factory', '', 0);
	$factory = cache_factory::initialize()->cache();
	//$factory = cache_factory::initialize()->cache('memcache');
	return $factory->get($name);
}

/**
 * 设置缓存
 * @param string 缓存标志
 * @param array  数据
 * @return boolean 是否成功
 */
function set_cache($name, $data)
{
	lk::lo('cache_factory', '', 0);
	$factory = cache_factory::initialize()->cache();
	//$factory = cache_factory::initialize()->cache('memcache');
	return $factory->set($name, $data);
}

/**
 * 删除缓存
 * @param string 缓存标志
 * @return boolean 是否删除成功
 */
function delete_cache($name)
{
	lk::lo('cache_factory', '', 0);
	$factory = cache_factory::initialize()->cache();
	//$factory = cache_factory::initialize()->cache('memcache');
	return $factory->delete($name);
}

/**
 * 向客户端设置cookie 实时生效
 * @access public
 * @param 名称
 * @param 值
 * @param 生命周期
 * @return NULL;
 */
function set_cookie($var, $value = '', $time = 0)
{
	$time = $time> 0 ? $time : ($value == '' ? TIME - 3600 : 0);
	$S    = $_SERVER['SERVER_PORT'] == '443' ? 1 : 0;
	$var  = COOKIE_PRE . $var;
	$_COOKIE[$var] = $value;
	if(is_array($value))
	{
		foreach($value as $k => $v)
		{
			setcookie($var . '[' . $k . ']', $v, $time, COOKIE_PATH, COOKIE_DOMAIN, $S);
		}
	}
	else
	{
		setcookie($var, $value, $time, COOKIE_PATH, COOKIE_DOMAIN, $S);
	}
}

/**
 * 获取cookie
 * @param string $var
 */
function get_cookie($var)
{
	$var = COOKIE_PRE . $var;
	return isset($_COOKIE[$var]) ? $_COOKIE[$var] : false;
}

/**
 * 隐藏ip
 */

/**
 * 获取客户端ip
 */
function get_ip()
{
	static $ip = null;
	if($ip)
	{
		return $ip;
	}
	if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown'))
	{
		$ip = getenv('HTTP_CLIENT_IP');
	}
	else if(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown'))
	{
		$ip = getenv('HTTP_X_FORWARDED_FOR');
	}
	else if(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown'))
	{
		$ip = getenv('REMOTE_ADDR');
	}
	else if(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown'))
	{
		$ip = $_SERVER['REMOTE_ADDR'];
	}
	return preg_match('/[\d\.]{7,15}/', $ip, $matchs) ? $matchs[0] : 'unknown';
}

/**
 * debug
 */
function debug()
{
	define('DEBUG_TIME', sprintf('%0.5f', microtime(true) - BEGIN_TIME));
	if(!defined('DEBUG') /*|| !defined('IN_ADMIN')*/ || !DEBUG /*|| !IN_ADMIN*/)
	{
		return false;
	}
	$sql_nums = class_exists('model') ? model::querynum() : 0;
	define('DEBUG_QUERIS', $sql_nums);
	unset($sql_nums);
	return true;
}

/**
 * 引入模板
 * 
 */
function template($file = 'index', $module = M)
{
	$template = lk::lo('template');
	$tplfile  = TPL_ROOT   . $module . DIRECTORY_SEPARATOR . $file . '.html';
	$tplcache = CACHE_PATH . 'cache_template' . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . $file . '.php';
	if(!file_exists($tplfile))
	{
		showmsg("Template file \"$tplfile\" not exists!");
	}
	if(!file_exists($tplcache) && file_exists($tplfile) || @filemtime($tplfile)> @filemtime($tplcache))
	{
		$template->template_compile($module, $file);
	}
	return $tplcache;
}

/**
 * 通用信息提示 showmsg
 * @access public
 * @param string  $msg 信息
 * @param boolean $isok 警告或正确或错误
 * @param string  $burl 返回url
 * @param boolean $jump
 * @param string  $dialog
 * @param boolean $top 是否跳出框架
 * @return null
 */
function showmsg($msg, $isok = false, $burl = '', $jump = true, $dialog = '', $top = false)
{
	$refresh = MINREFRESH * 1000;
	$titlecolor = $isok ? 'ok' : 'error';
	if($burl == '')
	{
		$url = HTTP_REFERER;
		$backurl = 'javascript:history.back()';
	}
	else
	{
		$url = $backurl = $burl;
	}
	$target = $top ? '_parent' : '_self';
	$parent = $top ? 'window.parent.' : '';
	include defined('IN_ADMIN') ? admin_common::admin_t('showmsg', 'admin') : template('showmsg', 'index');
	exit;
}

/**
 * 分页函数
 * @param int $total        总记录数
 * @param int $current_page 当前页数
 * @param int $pagesize     每页显示条数
 * @param int $select       是否跳转
 * @param int $input        是否输入页数GO
 * @param int $dot          是否显示缩略1...7,8,9...100
 * @param int $t            是否显示统计
 * @param string $url       网址
 */
function page($total, &$current_page, $pagesize = 20, $select = 1, $input = 0, $dot = 1, $t = 0, $url = '')
{
	$s_n = $i_n = $d_n = $t_n = $dot_1 = $first_a = $prev_a = $next_a = $last_a = '';
	if(!$url)
	{
		$url = new_parse_url("page=$current_page");
	}
	$pages = ceil($total/$pagesize);
	if($current_page>=$pages)
	{
		$current_page = $pages;
	}
	if($pages> 1)
	{
		$prev  = ($current_page - 1)>= 0 ? $current_page - 1 : 0;
		$next  = ($current_page + 1) <=$pages ? $current_page + 1 : 0;
		if($prev)
		{
			$first_a = '<a href="' . new_parse_url("page=1", $url) . '" target="_self">' . LANG('page_first') . '</a>';
			$prev_a  = '<a href="' . new_parse_url("page=$prev", $url) . '" target="_self">' . LANG('page_prev') . '</a>';
		}
		else
		{
			$first_a = '<span class="disabled">' . LANG('page_first') . '</span>';
			$prev_a  = '<span class="disabled">' . LANG('page_prev') . '</span>';
		}
		if($next)
		{
			$next_a = '<a href="' . new_parse_url("page=$next", $url) . '" target="_self">' . LANG('page_next') . '</a>';
			$last_a = '<a href="' . new_parse_url("page=$pages", $url) . '" target="_self">' . LANG('page_last') . '</a>';
		}
		else
		{
			$next_a = '<span class="disabled">' . LANG('page_next') . '</span>';
			$last_a = '<span class="disabled">' . LANG('page_last') . '</span>';
		}
		if($dot)
		{
			$size = 7;						//中间码宽度
			$mid = ceil($size / 2);			//中间码的序号
			$start = $current_page - $mid;  //中间码的起始页码
			$dot_1 = $current_page == 1 ? '<span class="current">1</span>' : '<a href="' . new_parse_url("page=1", $url) . '">1</a>';
			for($i = 1; $i <=$size; $i++)
			{
				$code = $start + $i;		//中间几个累加页码
				if($code <=1)
				{
					continue;
				}
				if($code == $pages)
				{
					break;
				}
				if($i == 1 && $code> 2)
				{
					$dot_1 .= '... ';
				}
				if($code == $current_page)
				{
					$dot_1 .= '<span class="current">' . $current_page . "</span>";
				}
				else
				{
					$dot_1 .= '<a href="' . new_parse_url("page=$code", $url) . "\" target='_self'>$code</a>";
				}
				if($i == $size && $code <=$pages && $pages>= $size)
				{
					$dot_1 .= '... ';
				}
			}
			$dot_1 .= $current_page == $pages ? "<span class='current'>$pages</span>" : '<a href="' . new_parse_url("page=$pages", $url) . '" target="_self">' . $pages . "</a>";
		}
		else
		{
			//其他分页方式
		}
		if($select)
		{
			$s_n = "<select onchange='window.location.href=\"" . new_parse_url("page=", $url) . "\" + this.value'>";
			for($i = 1; $i <= $pages; $i ++)
			{
				$selected = $current_page == $i ? 'selected="selected"' : '';
				$s_n .= "<option value='$i' $selected>$i</option>";
			}
			$s_n .= "</select>";
		}
		if($input)
		{
		$i_n = '跳转<input type="text" id="ipage" name="ipage" onkeydown="return only_input_num(event)" onpaste="return false" />';
		$i_n .= "\n<input type='button' id='is' name='isub' value='" . LANG('page_go') . "' onclick='go()' />\n";
		$i_n .= '<script type="text/javascript">
function only_input_num(e)
{
	var keynum;
	var keychar;
	var numcheck;
	if(window.event) // IE
	{
 		keynum = e.keyCode;
  	}
	else if(e.which) // Netscape/Firefox/Opera
  	{
  		keynum = e.which;
  	}
	keychar = String.fromCharCode(keynum);
	if(keynum == 13){go()}
	if(keynum == 46 || keynum == 8 || (keynum>=96 && keynum <=105))
	{
		return true;
	}
	numcheck = /\d/
	return numcheck.test(keychar)
}
function go()
{
	var page = document.getElementById("ipage").value;
	var re   = /[0-9]+/;
	if(re.test(page) == false)
	{
		alert("' . LANG('page_only_number') . '");
		document.getElementById("ipage").focus();
		return false;
	}
	if(page<1 || parseInt(page) == "NaN" || page>' . $pages . ')
	{
		alert("'. LANG('page_wrong_number') .'");
		document.getElementById("ipage").focus();
		return false;
	}
	window.location.href=' . "\"" . new_parse_url('page=', $url) . "\"+ parseInt(page)" . ';
}
</script>';
		}
	}
	
	if($t)
	{
		$from = max(($current_page - 1) * $pagesize + 1, 0);
		$to   = min($total, $current_page * $pagesize);
		$t_n  = sprintf(LANG('page_total'), $from, $to, $total);
	}
	$nav  = "<div class=\"pager\">";
	$nav .= $t_n . $first_a . $prev_a . $dot_1 . $next_a . $last_a . $s_n . $i_n;
	$nav .= "</div>\n";
	return $nav;
}

/**
 * 取当前页面完整地址
 */
function url()
{
	$http = (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) ? 'https://' : 'http://';
	$php_self = $_SERVER['PHP_SELF'] ? safe_replace($_SERVER['PHP_SELF']) : safe_replace($_SERVER['SCRIPT_NAME']);
	$path_info = isset($_SERVER['PATH_INFO']) ? safe_replace($_SERVER['PATH_INFO']) : '';
	$relate_url = isset($_SERVER['REQUEST_URI']) ? safe_replace($_SERVER['REQUEST_URI']) : $php_self . (isset($_SERVER['QUERY_STRING']) ? '?' . safe_replace($_SERVER['QUERY_STRING']) : $path_info);
	return $http . (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '') . $relate_url;
}

/**
 * 取得当前页面相对网址
 */
function relative_url()
{
	$path_info = isset($_SERVER['PATH_INFO']) ? safe_replace($_SERVER['PATH_INFO']) : '';
	$query_string = isset($_SERVER['QUERY_STRING']) ? safe_replace($_SERVER['QUERY_STRING']) : '';
	$dot = $path_info && $query_string ? '?' : '';
	return $path_info . $dot . $query_string;
}

/**
 * 解析url 将网址加入传入的ext组成新网址
 * @param string $ext 类似 "a=1&b=2"
 * @param string $url 网址
 * @return string 组装之后的网址 将覆盖掉原url中与$ext重复的部分
 */
function new_parse_url($ext = '', $url = '')
{
	if(!$url)
	{
		$url = url();
	}
	$pos = strpos($url, '?');
	if($pos !== false)
	{
		$url_arr = parse_url($url);
		$query = $url_arr['query'];
		unset($url_arr);
		parse_str($query, $url_arr);
		parse_str($ext, $ext_arr);
		$url_arr = array_merge($url_arr, $ext_arr);
		foreach($url_arr as $u_key => $u_value)
		{
			$querys[$u_key] = $u_value;
		}
		$query = http_build_query($querys);
		$new_url = substr($url, 0, $pos) . '?' . $query;
	}
	else
	{
		$new_url = $url . '?' . $ext;
	}
	return $new_url;
}

/**
 * 转义字符串
 * @param string/array $data
 * @return mixed 
 */
function new_addslashes($data)
{
	return is_array($data) ? array_map('new_addslashes', $data) : addslashes(trim($data));
}

/**
 * 反转义字符串
 * @param string/array $data
 * @return mixed 
 */
function new_stripslashes($data)
{
	return is_array($data) ? array_map('new_stripslashes', $data) : stripslashes(trim($data));
}

/**
 * 过滤html标签
 * @access public
 * @param string $string 字符串
 * @return clean $string
 */
function new_htmlspecialchars($string)
{
	return is_array($string) ? array_map('new_htmlspecialchars', $string) : htmlspecialchars($string, ENT_QUOTES);
}

/**
 * 转成html标签
 * @access public
 * @param string/array $string 字符串或数组
 * @return mixed $string
 */
function new_htmlspecialchars_decode($string)
{
	return is_array($string) ? array_map('new_htmlspecialchars_decode', $string) : htmlspecialchars_decode($string, ENT_QUOTES);
}

/**
 * 安全过滤函数
 * @param $string
 * @return string
 */
function safe_replace($string) {
	$string = str_replace('%20','',$string);
	$string = str_replace('%27','',$string);
	$string = str_replace('%2527','',$string);
	$string = str_replace('*','',$string);
	$string = str_replace('"','&quot;',$string);
	$string = str_replace("'",'',$string);
	$string = str_replace('"','',$string);
	$string = str_replace(';','',$string);
	$string = str_replace('<','&lt;',$string);
	$string = str_replace('>','&gt;',$string);
	$string = str_replace("{",'',$string);
	$string = str_replace('}','',$string);
	return $string;
}

/**
 * 安全过滤函数 递归
 * @param mixed $arrstr
 * @return clean string/array
 */
function new_safe_replace($arrstr)
{
	return is_array($arrstr) ? array_map("safe_replace", $arrstr) : safe_replace($arrstr);
}

/**
 * 浏览器友好的变量输出
 */
function dump($var, $echo = true, $label = null, $strict = true)
{
    $label = ($label===null) ? '' : rtrim($label) . ' ';
    if(!$strict)
	{
        if (ini_get('html_errors'))
		{
            $output = print_r($var, true);
            $output = "<pre>" . $label . htmlspecialchars($output, ENT_QUOTES) . "</pre>";
        }
		else
		{
            $output = $label . " : " . print_r($var, true);
        }
    }
	else
	{
        ob_start();
        var_dump($var);
        $output = ob_get_clean();
        if(!extension_loaded('xdebug'))
		{
            $output = preg_replace("/\]\=\>\n(\s+)/m", "] => ", $output);
            $output = '<pre>' . $label. htmlspecialchars($output, ENT_QUOTES) . '</pre>';
        }
    }
    if($echo)
	{
        echo $output;
        return null;
    }
	else
	{
        return $output;
	}
}

/**
 * 错误处理调用,将错误写入日志文件
 * @access public
 * @param string $errno
 * @param string $errstr 
 * @param string $errfile
 * @param integer $errline
 * @param string $vars
 * @return null
 */
function lkerror($errno, $errstr, $errfile, $errline, $vars)
{
	$log = LOG_PATH . 'lk_error_' . date('Y_m', TIME) . '.log';
	$filename = str_replace(LK_ROOT , '', $errfile);
	$date = date('Y-m-d H:i:s');
	$errorPort = array(	
	E_ERROR           => 'Error',
	E_WARNING         => 'Warning',
	E_PARSE           => 'Parsing Error',
	E_NOTICE          => 'Notice',
	E_CORE_ERROR      => 'Core Error',
	E_CORE_WARNING    => 'Core Warning',
	E_COMPILE_ERROR   => 'Compile Error',
	E_COMPILE_WARNING => 'Compile Warning',
	E_USER_ERROR      => 'User Error',
	E_USER_WARNING    => 'User Warning',
	E_USER_NOTICE     => 'User Notice',
	E_STRICT          => 'Runtime Notice'
	);
	$user_error = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE);
	$err  = $date . "_@#";
	$err .= $errno . '_@#';
	$err .= $errorPort["$errno"] . '_@#';
	$err .= $errstr . '_@#';
	$err .= $filename . "_@#" . $errline . "\n";
	if(in_array($errno, $user_error))
	{
		$err['vars']= $vars;
	}
	if(!file_exists($log))
	{
		$fp = fopen($log, 'w');
		fclose($fp);
	}
	error_log($err, 3, $log);	//模式3，将错误日志写入文件
	@chmod($log, 0777);
	die('出现错误，请查看错误日志 <a href="?m=admin&c=develop_log&a=errorlog" target="main">错误日志</a>');
}

/**
 * 读取错误日志
 */
function read_log()
{
	$content = '';
	if(is_dir(LOG_PATH) && $dp = opendir(LOG_PATH))
	{
		while(false !== ($fp = readdir($dp)))
		{
			if($fp != '.' && $fp != '..')
			{
				$content .= file_get_contents(LOG_PATH . $fp);
			}
		}	
	}
	return $content;
}

/**
 * 加载语言包
 * @param string $key 键值
 * @param string $modules 其他模块 多个模块 mod1,mod2
 */
function LANG($key, $modules = '')
{
	static $LANG = array();
	$file = LANG_PATH . 'base.lang.php'; //基础语言包
	$mfile = LANG_PATH . M . '.lang.php'; //当前模块语言包
	if(!$LANG)
	{
		include $file;
		if(is_file($mfile))
		{
			include $mfile;
		}
	}
	if($modules)
	{
		$modulearr = explode(',', $modules);
		foreach($modulearr as $_val)
		{
			if(is_file(LANG_PATH . $_val . '.lang.php'))
			{
				include LANG_PATH . $_val . '.lang.php';
			}
		}
	}
	return isset($LANG[$key]) ? $LANG[$key] : sprintf($LANG['need_language_support'], $key);
}

/**
 * 取得文件后缀名
 *
 */
function fileext($filename)
{
	return strtolower(trim(substr(strrchr($filename, '.'), 1)));
}
function fileext2($filename)
{
	$ext = pathinfo($filename);
	$ext = $ext['extension'];
	return strtolower(trim($ext));
}